using System;
using System.Collections.Generic;
using System.Text;

namespace TuringMachine.StateAutomat
{
    class TransactionTable
    {
        private Dictionary<FromConfiguration, ToConfiguration> transactionTable = null;

        public TransactionTable()
        {
            transactionTable = new Dictionary<FromConfiguration, ToConfiguration>();
        }

        public void AddTransaction(State fromState, char inputChar, State toState, char tapeAction)
        {
            FromConfiguration _from = new FromConfiguration(fromState, inputChar);
            ToConfiguration _to = new ToConfiguration(toState, tapeAction);
            ///TODO: Check determenistic if _from conf already exist
            transactionTable.Add(_from, _to);
        }

        public bool IsFromConfigurationExist(State fromState, char inputChar)
        {
            bool _ret = false;
            foreach (FromConfiguration _toCheck in transactionTable.Keys)
            {
                if ((fromState.Name == _toCheck.PairState.Name) && (inputChar == _toCheck.PairChar))
                {
                    _ret = true;
                    break;
                }
            }
            return _ret;
        }

        public FromConfiguration GetFromConfigurationInstance(State fromState, char inputChar)
        {
            FromConfiguration _ret = null;
            foreach (FromConfiguration _toCheck in transactionTable.Keys)
            {
                if ((fromState.Name == _toCheck.PairState.Name) && (inputChar == _toCheck.PairChar))
                {
                    _ret = _toCheck;
                    break;
                }
            }
            return _ret;
        }

        public ToConfiguration GetToConfiguration(FromConfiguration fromConfiguration)
        {
            ToConfiguration _ret = null;
            if (transactionTable.ContainsKey(fromConfiguration))
            {
                _ret = transactionTable[fromConfiguration];
            }
            return _ret;
        }
    }

    class FromConfiguration : IPair
    {
        private State fromState;
        private char inputChar;

        public FromConfiguration(State fromState, char inputChar)
        {
            this.PairState = fromState;
            this.PairChar = inputChar;
        }
        #region IPair Members

        public State PairState
        {
            get
            {
                return fromState;
            }
            set
            {
                fromState = value;
            }
        }
        public char PairChar
        {
            get
            {
                return inputChar;
            }
            set
            {
                inputChar = value;
            }
        }

        #endregion
    }

    class ToConfiguration : IPair
    {
        private State toState;
        private char tapeAction;
        public ToConfiguration(State toState, char tapeAction)
        {
            this.PairState = toState;
            this.PairChar = tapeAction;
        }
        #region IPair Members

        public State PairState
        {
            get
            {
                return  toState;
            }
            set
            {
                toState = value;
            }
        }

        public char PairChar
        {
            get
            {
                return tapeAction;
            }
            set
            {
                tapeAction = value;
            }
        }

        #endregion
    }
}
